DisqueのTTLとRetryについて


概要

TTLとRetry組み合わせた際の挙動がよくわかってなかったのでメモっておく。


Disqueはなんか分散ジョブキュー。

Disque

https://github.com/antirez/disque


使ってるクライアントは自作のDisquuun。

Disquuun

https://github.com/sassembla/Disquuun



TTL

Time To Live なのでDisque-serverに登録したジョブの生存時間。

Disqueの場合はAddJobコマンドのオプションでジョブ追加の都度指定する。


Disquuunの場合だと次のようなコードになる。

disquuun.AddJob("queueName", new byte[]{0,1,2}, 0, "TTL", 1);

TTLの単位はsecなので、これでDisque-server側にこのジョブは、ジョブがキュー"queueName"に追加されて1秒経つと消滅する。

ただし、デフォルトのDisqueの設定だと、こういったタイマーに関する分解能が10hz(秒間10回)程度になっているので、わりとやんわりとした動作になっている。


ちなみにTTLを指定しなかった場合のデフォルト値は 1day = 86400sec とか。


Retry

リトライ、なんかちゃんと向き合っていなかったのだけれど、

Retry値は、GetJobされたジョブが、再びキューに入るまでの時間を指定するパラメータになっている。


指定はDisquuunの場合だと次のようなコードになる。

disquuun.AddJob("queueName", new byte[]{0,1,2}, 0, "RETRY", 1);



この辺の挙動はテストケース書いたんで具体的にこうなるんだぜみたいな例がある。

https://github.com/sassembla/Disquuun/blob/master/DisquuunTest/Tests_1.cs#L64


Retryの値に関する仕様は以下のようになってるらしい。

・デフォルト値は5分

一度GetJobされてから5分経ったら、再装填が発生する。


・0ならば"最大で1回送付"モードになる

んでGetJobが発生したら実際にどうなるの?っていうと、これが面白かったので後述する。


・0より大きい数値ならば単位はsecで、この秒数が過ぎたら再装填が発生する

この値の指定と効果には特例があって、


TTLが指定してあり、かつ、TTL x 0.1(sec) < RETRY指定値(デフォの場合は5min)の場合、RETRY値はTTL x 0.1(sec) に指定される。

例えばTTLを5分にした場合、5x60sec(TTL) x 0.1 < 5x60sec(RETRY) なので、RETRY値は自動的に 5x60sec(TTL) x 0.1になる。


なにがなんでもRETRYさせたいらしい。まあ明示的に指定してるんだしな。



最大で1回送付 モードになるって実際にはどういう挙動なの?

ここまでで、TTLでジョブの寿命が、Retryでジョブの再装填が制御できることがわかった。

で、例えば次のような指定をした場合どうなるのか。

case1.Retry = 0

case2.TTL = 10sec

case3.Retry = 0 + TTL = 10sec



case1.Retry = 0

Retryが0なので、GetJobしたらackしないでも二度とキューに現れない。

ジョブ自体はどうなっちゃうんだろう?


var len0 = DisquuunDeserializer.Qlen(disquuun.Qlen("queueName").DEPRICATED_Sync());

このlen0は確かに0になる。


が、


var info = DisquuunDeserializer.Info(disquuun.Info().DEPRICATED_Sync());

var restJobCount = info.jobs.registered_jobs;


infoから取得するrestJobCountは、これなんと1件になる。

残っとるんかワレ。しかも二度と"queueName"には登らないだと、、、


別にRetry = 0時のみの特殊な挙動ではなくて、

Retryの値がなんであれ、例えばRetry指定をしてない場合は、

・5分経つまでキューの外で待つ(qlenは0を返す

・じゃあどこにいるの、っていうと、Infoでは見えるどこかにいる

という挙動になるみたいだ。


ちなみにRetry = 0だと、再装填は発生しない + TTL未指定なので、TTLデフォルトの1日が経過するのを待って死ぬ感じ。



case2.TTL = 10sec

Retryがデフォ5min -> TTLの10%より小さいので、RetryはTTLの10% = 1secになる。

つまりGetJobとかが発生すると、1秒で復帰してくる。


Disqueのフレームレートがデフォルト10hzなので、まあ10秒間の寿命の中できっちり10回再装填されることは無いと思うけれど、

なるほど1秒で再装填されるのか、、と思うと感慨深い。



case3.Retry = 0 + TTL = 10sec

というわけで、Retryを明示的に0にセットし、TTLを10secにした場合、

・ジョブは一度GetJobされたりすると、キューからは外れる

・Retry = 0なので二度とキューに再装填されない

・TTLが10secなので10秒したら死ぬ

というのが起こる。



以上。